package work.parabola.assets.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author 黄松祥
 *
 *         2018年3月28日 下午9:23:56
 */
public class FtpUtil {

	private static final Logger log = LoggerFactory.getLogger(FtpUtil.class);

	private static String ftpIp = PropertiesUtil.getProperty("ftp.server.ip");

	private static int ftpPort = Integer.valueOf(PropertiesUtil.getProperty("ftp.server.port"));

	private static String ftpUser = PropertiesUtil.getProperty("ftp.user");

	private static String ftpPassword = PropertiesUtil.getProperty("ftp.password");

	private FTPClient ftpClient;

	private String ip;
	private int port;
	private String user;
	private String password;

	public FtpUtil(String ip, int port, String user, String password) {
		this.ip = ip;
		this.port = port;
		this.user = user;
		this.password = password;
	}
	//上传多个文件-对外提供静态方法
	public static boolean uploadFiles(List<File> fileList, String remotePath) {
		FtpUtil ftpUtil = new FtpUtil(FtpUtil.ftpIp, FtpUtil.ftpPort, FtpUtil.ftpUser, FtpUtil.ftpPassword);
		log.info("连接FTP服务器，开始上传文件");
		boolean result = ftpUtil.uploadFile(remotePath, fileList);
		log.info("上传文件结束，上传结果{}", result);
		return result;
	}
	//上传单个文件-对外提供静态方法
	public static boolean uploadFile(File file, String remotePath) {
		List<File> fileList = new ArrayList<>();
		fileList.add(file);
		return FtpUtil.uploadFiles(fileList, remotePath);
	}
	//判断ftp服务器上该目录下对应的文件是否存在-对外提供静态方法
	public static boolean fileExists(String remotePath, String filename) {
		FtpUtil ftpUtil = new FtpUtil(FtpUtil.ftpIp, FtpUtil.ftpPort, FtpUtil.ftpUser, FtpUtil.ftpPassword);
		boolean exists = false;
		try {
			exists = ftpUtil.isExists(remotePath, filename);
		} catch (IOException e) {
			log.error("FTP服务器异常", e);
			exists = false;
		}
		return exists;
	}
	//删除多个文件-提供静态方法
	public static void deleteFiles(List<String> fileList,String remotePath) {
		FtpUtil ftpUtil = new FtpUtil(FtpUtil.ftpIp, FtpUtil.ftpPort, FtpUtil.ftpUser, FtpUtil.ftpPassword);
		try {
			ftpUtil.delete(fileList, remotePath);
		} catch (IOException e) {
			log.error("FTP服务器异常，删除文件错误", e);
		}
	}
	//删除一个文件-提供静态方法
	public static void deleteFile(String filename, String remotePath) {
		List<String> fileList = new ArrayList<>();
		fileList.add(filename);
		FtpUtil.deleteFiles(fileList, remotePath);
	}
	//下载一个文件-提供静态方法
	public static boolean download(String filename, String remotePath, OutputStream os) {
		FtpUtil ftpUtil = new FtpUtil(FtpUtil.ftpIp, FtpUtil.ftpPort, FtpUtil.ftpUser, FtpUtil.ftpPassword);
		boolean success = true;
		try {
			success = ftpUtil.downloadFile(remotePath, filename, os);
		} catch (IOException e) {
			log.error("下载文件失败", e);
			success = false;
		}
		return success;
	}
	
	private void delete(List<String> fileList, String remotePath) throws IOException {
		if(this.connectServer(this.ip, this.port, this.user, this.password)) {
			if(this.ftpClient.changeWorkingDirectory(remotePath)) {
				for(String filename : fileList) {
					ftpClient.deleteFile(filename);
				}
			}
			this.ftpClient.disconnect();
		}
	}

	//判断文件ftp服务器上文件是否存在
	private boolean isExists(String remotePath, String filename) throws IOException {
		boolean exists = true;
		if (this.connectServer(this.ip, this.port, this.user, this.password)) {
			if (!this.ftpClient.changeWorkingDirectory(remotePath)) {
				exists = false;
			} else {
				FTPFile[] ftpFileList = this.ftpClient.listFiles(filename);
				if (ftpFileList.length == 0) {
					exists = false;
				}
				this.ftpClient.disconnect();
			}
			
		}
		return exists;
	}
	//从ftp服务器上下载文件
	private boolean downloadFile(String remotePath, String filename, OutputStream os) throws IOException {
		boolean success = true;
		if(this.connectServer(this.ip, this.port, this.user, this.password)) {
			if(!this.ftpClient.changeWorkingDirectory(remotePath)) {
				success = false;
			} else {
				success = this.ftpClient.retrieveFile(filename, os);
			}
			this.ftpClient.disconnect();
			
		} else {
			return success = false;
		}
		return success;
	}

	//连接ftp服务器
	private boolean connectServer(String ip, int port, String user, String password) {
		boolean isSuccess = false;

		this.ftpClient = new FTPClient();
		try {
			ftpClient.connect(ip, port);
			isSuccess = ftpClient.login(user, password);
		} catch (IOException e) {
			log.error("连接FTP服务器失败", e);
		}
		return isSuccess;
	}

	//上传文件
	private boolean uploadFile(String remotePath, List<File> fileList) {
		boolean uploaded = false;

		FileInputStream fis = null;
		// 连接FTP服务器
		if (this.connectServer(this.ip, this.port, this.user, this.password)) {
			try {
				if (!this.ftpClient.changeWorkingDirectory(remotePath)) {
					this.ftpClient.makeDirectory(remotePath);
					this.ftpClient.changeWorkingDirectory(remotePath);
				}
				this.ftpClient.setBufferSize(1024);
				this.ftpClient.setControlEncoding("UTF-8");
				this.ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
				this.ftpClient.enterLocalPassiveMode();
				for (File file : fileList) {
					fis = new FileInputStream(file);

					uploaded = this.ftpClient.storeFile(file.getName(), fis);
					fis.close();
					fis = null;
				}
			} catch (IOException e) {
				log.error("文件上传异常", e);
			} finally {
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						log.error("发送FTP数据流关闭异常", e);
					}
				}
				try {
					this.ftpClient.disconnect();
				} catch (IOException e) {
					log.error("与FTP服务器中断连接异常", e);
				}
			}
		}
		return uploaded;
	}

}
